package main

import "fmt"

type A struct {
	Name string
	age  int
}

type B struct {
	Name  string
	Score float64
}

type C struct {
	A
	B
	//Name string
}

type D struct {
	a A //组合方式  有名的结构体
}

type Goods struct {
	Name  string
	Price float64
}

type Brand struct {
	Name    string
	Address string
}

type TV struct {
	Goods
	Brand
}

type TV2 struct {
	*Goods
	*Brand
}

type Monster struct {
	Name string
	Age  int
}

type E struct {
	Monster
	//基本数据类型也可以当匿名字段
	//如果一个结构体有int类型的匿名字段 就不能再有第二个
	//如果有需要多个int的字段则必须给int字段指定名字
	int
	n int
}

func main() {

	var c C
	//如果c没有Name字段 而A和B有Name
	//这时就必须通过指定匿名结构体名字来区分
	//所以c.Name就会编译报错
	c.A.Name = "tom"
	fmt.Println("c")

	//如果D中是一个有名结构体，则访问有名结构体的字段时
	//就必须带上有名结构体的名字 比如 d.a.Name
	var d D
	d.a.Name = "jack"

	//嵌套匿名结构体后，也可以在创建结构体变量（实例）时
	//直接指定各个匿名结构体字段的值
	tv := TV{Goods{"电视机", 500.9}, Brand{"海尔", "山东"}}

	//演示访问Goods的Name
	fmt.Println(tv.Goods.Name)
	fmt.Println(tv.Price)

	tv2 := TV{
		Goods{
			Price: 200.9,
			Name:  "电视机2",
		},
		Brand{
			Name:    "夏普",
			Address: "北京",
		},
	}

	fmt.Println("tv=", tv)
	fmt.Println("tv2=", tv2)

	tv3 := TV2{&Goods{"电视机3", 300.9}, &Brand{"创维", "河南"}}

	tv4 := TV2{
		&Goods{
			Name:  "电视机004",
			Price: 9000.99,
		},
		&Brand{
			Name:    "长虹",
			Address: "四川",
		},
	}
	fmt.Println("tv3", *tv3.Goods, *tv3.Brand)

	fmt.Println("tv4", *tv4.Goods, *tv4.Brand)

	//演示一下匿名字段时基本数据类型的使用
	var e E
	e.Name = "狐狸精"
	e.Age = 300
	e.int = 20
	e.n = 40
	fmt.Println("e=", e)
}
